package com.iiot.stream.tools;

import com.htiiot.common.db.DbConnectionPool;
import com.htiiot.common.db.JDBCUtils;
import com.htiiot.common.util.JedisMultiPool;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import redis.clients.jedis.Jedis;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Map;

/**
 * 本类同步redis中设备上一天的在线时长和离线时长到Mysql的ting_device_rate表中
 *
 * @author dzm
 * @create 2018-07-25-17:12
 */
public class RedisToMysqlDeviceRate implements Job{
    private static Logger logger = Logger.getLogger(RedisToMysqlDeviceRate.class);
    SimpleDateFormat tf = new SimpleDateFormat("yyyy-MM-dd");
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        String yestoday = tf.format(System.currentTimeMillis() - 86400000L);
        int num = 0;
        logger.info("---- 定时时间到，开始同步:" + yestoday + " 日的数据 ----");
        // 获取 redis 连接
        Jedis redisHandle = JedisMultiPool.getJedis();
        // mysql连接
        DbConnectionPool pool = DbConnectionPool.getPool();
        Connection conn  = pool.getConnection();
        PreparedStatement psToRate = null;
        ResultSet rs = null;
        try{
            conn.setAutoCommit(false);
            psToRate = conn.prepareStatement("INSERT INTO `thing_device_rate` " +
                    "(device_id,online,warning,standby,offline,thing_date) " +
                    "SELECT id,?,?,?,?,? FROM thing_device WHERE id = ? " +
                    "AND deleted = 0 AND TYPE = 0");
            // 获取所有did
            String[] allDid = redisHandle.hkeys("deviceStatus").toArray(new String[]{});
            // 获取所有状态下的设备的所有时长
            Map<String, String> runLengthMap = redisHandle.hgetAll("deviceStatus:run:" + yestoday);
            Map<String, String> standbyLengthMap = redisHandle.hgetAll("deviceStatus:standby:" + yestoday);
            Map<String, String> faultLengthMap = redisHandle.hgetAll("deviceStatus:fault:" + yestoday);
            Map<String, String> offLengthMap = redisHandle.hgetAll("deviceStatus:off:" + yestoday);
            // 获取当前系统时间
            long currentTime = System.currentTimeMillis();
            // 遍历每一个did，进行汇总
            for(int i = 0;i < allDid.length;i++){
                String tiddid = allDid[i];
                int did = Integer.parseInt(tiddid.split(":")[1]);
                float runTime = Float.parseFloat(runLengthMap.getOrDefault(tiddid,"0"))/(60 * 60 * 1000);
                float standbyTime = Float.parseFloat(standbyLengthMap.getOrDefault(tiddid,"0"))/(60 * 60 * 1000);
                float faultTime = Float.parseFloat(faultLengthMap.getOrDefault(tiddid,"0"))/(60 * 60 * 1000);
                float offTime = Float.parseFloat(offLengthMap.getOrDefault(tiddid,"0"))/(60 * 60 * 1000);
                if(runTime == 0 && standbyTime == 0 && faultTime == 0 && offTime == 0){
                    continue;
                }else{
                    psToRate.setFloat(1,runTime);
                    psToRate.setFloat(2,faultTime);
                    psToRate.setFloat(3,standbyTime);
                    psToRate.setFloat(4,offTime);
                    psToRate.setString(5,did + yestoday);
                    psToRate.setInt(6,did);
                    psToRate.addBatch();
                    num = num + 1;
                }
                if(num >= 100){
                    num = 0;
                    psToRate.executeBatch();
                    psToRate.clearBatch();
                    conn.commit();
                }
            }
            try {
                psToRate.executeBatch();
                psToRate.clearBatch();
                conn.commit();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            logger.info("同步用时---》" + (System.currentTimeMillis() - currentTime)/1000 + "s");
        }catch (Exception e){
            e.printStackTrace();
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }finally{
            redisHandle.close();
            JDBCUtils.close(psToRate, rs, conn);
        }
    }
}
